﻿#include "FITKAcousticsVTKGraphObjectSensor.h"
#include "FITKAcousticsVTKGraphActor.h"
#include "FITKAcousticsVTKSharedDataManager.h"

#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSensors.h"
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"

#include <vtkArrowSource.h>
#include <vtkDoubleArray.h>
#include <vtkGlyph3D.h>
#include <vtkPointData.h>
#include <vtkProperty.h>

namespace Exchange
{
    FITKAcousticsVTKGraphObjectSensor::FITKAcousticsVTKGraphObjectSensor(Acoustics::FITKAcousticsSensors * sensor):
        FITKAcousticsVTKGraphObject3D(sensor)
    {
        if (sensor == nullptr){
            return;
        }

        // Initialize vtk objects.
        init();

        //数据集生成
        if (!generateDataSet()){
            return;
        }

        generateGraph();

        // Update the visibility.
        updateVisibility();

        // Save the data type.
        m_graphInfo.Type = FITKAcousticsVTKCommons::SensorGraph;
    }

    FITKAcousticsVTKGraphObjectSensor::~FITKAcousticsVTKGraphObjectSensor()
    {
        deleteVtkObj(_picData);
        deleteVtkObj(_points);
        deleteVtkObj(_polydata);
        deleteVtkObj(_directions);
        deleteVtkObj(_glyph3D);
    }

    bool FITKAcousticsVTKGraphObjectSensor::getDataVisibility()
    {
        bool dataVisible = this->Superclass::getDataVisibility();
        bool showSensor = getRuntimeSettingAs<bool>(RTS_KEY_VISIBLE_SENSOR, true);
        return dataVisible && showSensor;
    }

    void FITKAcousticsVTKGraphObjectSensor::update(bool forceUpdate)
    {
        if (_graphActor == nullptr)return;

        if (forceUpdate) {
            generateDataSet();
        }

        _graphActor->SetVisibility(getDataVisibility());
    }

    void FITKAcousticsVTKGraphObjectSensor::setPickMode(FITKAcousticsVTKCommons::ShapePickMode mode)
    {
        if (!_graphActor) {
            return;
        }

        switch (mode)
        {
        case Exchange::FITKAcousticsVTKCommons::PickAll:
            _graphActor->SetPickable(true);
            break;
        default:
            _graphActor->SetPickable(false);
            break;
        }
    }

    void FITKAcousticsVTKGraphObjectSensor::highlight(FITKAcousticsVTKCommons::ShapeType type, QColor color)
    {
        Q_UNUSED(type);
        Q_UNUSED(color);
        if (_graphActor == nullptr && _graphActor->GetProperty())return;
        _graphActor->GetProperty()->SetRepresentation(VTK_WIREFRAME);
    }

    void FITKAcousticsVTKGraphObjectSensor::disHighlight()
    {
        if (_graphActor == nullptr && _graphActor->GetProperty())return;
        _graphActor->GetProperty()->SetRepresentation(VTK_SURFACE);
    }

    void FITKAcousticsVTKGraphObjectSensor::init()
    {
        FITKAcousticsVTKSharedDataManager* sharedDataManager = FITKAcousticsVTKSharedDataManager::GetInstance();
        if (sharedDataManager == nullptr) return;
        double bound[6] = { 0,0,0,0,0,0 };
        if (sharedDataManager->getSEANodesBounds(bound) == false)return;
        double length = std::sqrt(std::pow(bound[0] - bound[3], 2) + std::pow(bound[1] - bound[4], 2) + std::pow(bound[2] - bound[5], 2));
        length = length * 0.05;
        _picData = vtkArrowSource::New();
        //箭头维度
        _picData->SetTipResolution(10);
        //箭头半径
        _picData->SetTipRadius(0.5);
        //箭头长度
        _picData->SetTipLength(0.5);
        //箭柄维度
        _picData->SetShaftResolution(10);
        //箭柄半径
        _picData->SetShaftRadius(0.5);
        //设置箭头反向
        _picData->SetInvert(true);
        // 创建一个点集
        _points = vtkPoints::New();

        // 创建一个PolyData对象
        _polydata = vtkPolyData::New();
        _polydata->SetPoints(_points);

        // 创建一个方向数组
        _directions = vtkDoubleArray::New();
        _directions->SetNumberOfComponents(3);

        _polydata->GetPointData()->SetNormals(_directions);

        //使用vtkGlyph3D来生成箭头
        _glyph3D = vtkGlyph3D::New();
        _glyph3D->SetSourceConnection(_picData->GetOutputPort());
        _glyph3D->SetInputData(_polydata);
        _glyph3D->SetVectorModeToUseNormal();
        _glyph3D->SetScaleFactor(length);
    }

    bool FITKAcousticsVTKGraphObjectSensor::generateDataSet()
    {
        Acoustics::FITKAcousticsSensors* sensors = dynamic_cast<Acoustics::FITKAcousticsSensors*>(_dataObj);
        if (sensors == nullptr)return false;

        double orientation[3] = { 0,0,0 }, location[3] = { 0,0,0 };
        sensors->getGlobalOrientation(orientation);
        sensors->getLocation(location);

        resetVtkObj(_points);
        resetVtkObj(_directions);

        _directions->InsertNextTuple3(orientation[0], orientation[1], orientation[2]);
        _points->InsertNextPoint(location[0], location[1], location[2]);
        return true;
    }

    void FITKAcousticsVTKGraphObjectSensor::generateGraph()
    {
        QColor color(0, 110, 240);
        //创建可视化对象
        _graphActor = FITKAcousticsVTKGraphActor::New();
        _graphActor->setGraphObject(this);
        _graphActor->SetPickable(false);
        _graphActor->SetVisibility(true);
        _graphActor->GetProperty()->SetColor(color.redF(), color.greenF(), color.blueF());
        addActor(_graphActor);
        _graphActor->setInputConnection(_glyph3D->GetOutputPort());
    }
}

